#pragma once
#ifndef LOGIC_SERVER_MANAGER_H
#define LOGIC_SERVER_MANAGER_H

#include <map>

#include "google/protobuf/message.h"
#include "ProtoDispatch.h"
#include "LogicProtoBase.h"
#include "ProtoInc.h"
#include <stdexcept>

using namespace std;

class LogicServerManager : public LogicProtoBase
{
private:
	static LogicServerManager * pclassobj;

	LogicServerManager() {};

public:
	static LogicServerManager * GetInstance();

	virtual int RegProto();

	virtual int OnMessage(Message * msg, void * param);

	void AddNewConnect(unsigned fd)
	{ 
		fd_msg[fd] = NULL; 
	}

	void RemoveConnect(unsigned fd)
	{ 
		fd_msg.erase(fd);
	}

	void SetReplay(unsigned fd, Message * reply)
	{
		fd_msg[fd] = reply;
	}

private:
	map<unsigned, Message *>  fd_msg;   //fd与响应消息的映射
};

class ProtoManager
{
private:
	ProtoManager() {}
public:
	template<class T, class T2, class T3>
	static int ProcessProto(T *msg, void * param)
	{
		T2 * resp = new T2;
		unsigned fd = *(int *)param;

		try
		{
			int ret = T3::GetInstance()->Process(msg, resp);

			if (ret)
			{
				delete resp;
				resp = NULL;

				return ret;
			}

			LogicServerManager::GetInstance()->SetReplay(fd, resp);
		}
		catch(runtime_error &e)
		{
			delete resp;
			resp = NULL;

			Base::ErrRetReq * msg = new Base::ErrRetReq;
			msg->set_msg(e.what());

			LogicServerManager::GetInstance()->SetReplay(fd, msg);
		}

		return 0;
	}
};

#endif  //LOGIC_SERVER_MANAGER_H
